#ifndef _TEXTUREMANAGER_H_
#define _TEXTUREMANAGER_H_

#pragma warning ( disable:4786 )

#include <d3d9.h>
#include <utillib/memory/Memory.h>
#include <utillib/util/singleton.h>

#include <map>
#include <functional>

#include <interfacelib/directx/texture.h>

namespace interfacelib
{
	namespace DirectX
	{
		class TextureManager
		{
		private:
		template< class __T > struct Less : public std::binary_function< __T, __T, bool>
		{
			bool operator()(const __T& x, const __T& y) const
			{
				if ( ( !x ) || ( !y ) ) return true;
				
				return ( bool )( strcmp( ( const char * )x, ( const char * )y ) < 0 ? 1 : 0 ); 
			}
		};
			typedef std::map < char *, Texture * , Less < char * > > mapTextureList;
			
			mapTextureList m_textureList;
		protected:
			TextureManager();	
			typedef void ( interfacelib::DirectX::TextureManager::*__createTexture )( SpriteData *srcData );
			typedef void ( interfacelib::DirectX::TextureManager::*__drawTexture )( RECT *rect, D3DXVECTOR3 *vector, DWORD colorKey , SpriteData *currentSprite );
		public:
			virtual ~TextureManager();	

			SingletonInstance( TextureManager );

			void initialize( LPDIRECT3DDEVICE9 device , LPD3DXSPRITE sprite ){ m_D3DDevice = device;m_sprite = sprite;};
			void release();
			void releaseTexture();
			
			Texture *load( const char* filename );

			void remove( const char *fileName );
			HRESULT restoreDeviceObject();

			void setVoodooMode();
			bool isVoodooMode();

			void createTexture( SpriteData *srcData );
			void drawTexture( RECT *rect, D3DXVECTOR3 *vector, DWORD colorKey , SpriteData *currentSprite , D3DXVECTOR2 *scaling , int degree );
		private:
			__createTexture _createTexture; 
			__drawTexture _drawTexute;
			void createTextureCommon( SpriteData *srcData );
			void createTextureVoodoo( SpriteData *srcData );

			void drawTextureCommon( RECT *rect, D3DXVECTOR3 *vector, DWORD colorKey , SpriteData *currentSprite );
			void drawTextureVoodoo( RECT *rect, D3DXVECTOR3 *vector, DWORD colorKey , SpriteData *currentSprite );

			LPDIRECT3DDEVICE9 m_D3DDevice;
			BYTE *m_imageBuffer;
			bool m_voodooMode;
			LPD3DXSPRITE m_sprite;
			
			typedef std::map < WORD , MotionData * > mapMotion;

		};
	}
}

#endif
